/*
 * File      : bb_stack.c
 * This file is part of Black Bird Simulation Platform
 * Copyright 2013-2020 BB(Black Bird) Development Team.  
 * All rights reserved.
 *
 * Change Logs:
 * Date           Author       Notes
 * 2013-10-24     Holt         First Version
 * 2013-10-27	  Holt 		   free the data elem in bb_stack_free
 */
#include <stddef.h>
#include <assert.h>
#include "bb_mem.h"
#include "bb_stack.h"

/*
 * FUNC		:	Allocate a block of memory for the stack head.
 *
 * PARAM1	:	void
 *
 * RETURN 	:	pointer to allocated stack head memory or NULL if 
 *				no free memory was found.
 */
stack_t	bb_stack_new(void)
{
	stack_t stk=NULL;
	
	if(stk=bb_mem_new(sizeof(*stk)))
	{
		stk->cnt = 0;
		stk->head = NULL;
	}
	
	return stk;
}
/*
 * FUNC		:	Is the stack empty?
 *
 * PARAM1	:	stack  pointer
 *
 * RETURN 	:	if stack is empty , return 1; 
 *				else return 0;
 */
bb_bool	bb_stack_empty(const stack_t stk)
{
	assert(stk);
	return stk->cnt == 0;
}
/*
 * FUNC		:	Push a member into the stack.
 *
 * PARAM1	:	stack  pointer
 * PARAM2	:	pointer of member which is inserted.
 *
 * RETURN 	:	if stack is empty , return bb_TRUE; 
 *				else return bb_FALSE;
 */
bb_bool bb_stack_push(stack_t stk,const void *x)
{
	elem_t t;
	
	assert(stk);
	if(t=bb_mem_new(sizeof(*t)))
	{
		t->x = x;
		t->next = stk->head;
		stk->head = t;
		stk->cnt++;
		return bb_TRUE;
	}
	else
	{
		return bb_FALSE;
	}
}
/*
 * FUNC		:	Pop a member out of the stack.
 *
 * PARAM1	:	stack  pointer
 *
 * RETURN 	:	if stack is empty, return NULL; 
 *				else return pointer of the head data 
 */
void*	bb_stack_pop(stack_t stk)
{
	void *x;
	elem_t t;
	
	assert(stk);
	if (bb_stack_empty(stk))
		return NULL;
	else
	{
		t=stk->head;
		stk->head = t->next;
		stk->cnt--;
		x=t->x;
		bb_mem_free(t);
	
		return x;
	}
}
/*
 * FUNC		:	Free stack.
 *
 * PARAM1	:	stack  pointer
 *
 * RETURN 	:	 return bb_TRUE
 *				
 */
bb_bool bb_stack_free(stack_t stk)
{
	elem_t t;
	elem_t u;
	
	assert(stk);
	t = stk->head;
	while(t)
	{
		u=t->link;
		bb_mem_free(t->x);/*the data in elem where to free? by holt */
		bb_mem_free(t);
		t = u ->link;
	}
	bb_mem_free(stk);
	
	return bb_TRUE;
}